import 'dart:math';

import 'package:flame/components.dart';
import 'package:flame/effects.dart';
import 'package:flutter_flame/worlds/game/components/NormalZombieHead.dart';
import 'package:flutter_flame/worlds/game/entity/ZombieStateEnumType.dart';

import '../../../config/GameColors.dart';
import '../audio/SoundManager.dart';
import '../entity/SpriteAnimationParamEntity.dart';
import 'HealthBar.dart';
import 'BodyShadow.dart';
import 'plants/Plant.dart';
import '../../../component/SpriteAnimationEntity.dart';

final zombieWalkAnimations = [
  SpriteAnimationParamEntity.zombieWalk,
  SpriteAnimationParamEntity.zombieWalk2,
];
final zombieDeathAnimations = [
  SpriteAnimationParamEntity.zombieDeath,
  SpriteAnimationParamEntity.zombieDeath2,
];

// 僵尸行走
enum ZombieWalkType { type1, type2 }

// 僵尸类
class NormalZombie extends SpriteAnimationEntity {
  late int row; // 行
  late double speed = zombieSpeed; // 僵尸速度
  TimerComponent? _eatingTimer; // 吃植物
  Plant? _currentPlant; // 跟踪当前啃食的植物
  late double eatingPeriod = zombieEatingPeriod; // 僵尸吃植物间隔
  late double attack = zombieAttackPeriod; // 啃食伤害
  late double maxHp = zombieMaxHp; // 生命值
  HealthBar? healthBar; // 血条
  ZombieStateEnumType state = ZombieStateEnumType.walking; // 僵尸状态
  late BodyShadow bodyShadow; // 阴影

  NormalZombie(this.row, ZombieWalkType walkType)
      : super(zombieWalkAnimations[walkType.index]);

  factory NormalZombie.randomWalkType(int row) => NormalZombie(
        row,
        ZombieWalkType.values[Random().nextInt(ZombieWalkType.values.length)],
      );

  @override
  Future<void> onLoad() async {
    anchor = Anchor.topLeft;
    priority = zombiePriority;
    position = Vector2(
      game.size.x,
      lawnTopLeft.y + row * cellSize.y,
    );
    await super.onLoad();
    addHitBox(
      scaleHitBoxK: 0.8,
      hitBoxPosition: Vector2.zero(),
    );
    healthBar = HealthBar(
      maxHealth: maxHp,
      currentHealth: maxHp,
      healthBarWidth: 30,
      healthBarLeft: 12,
      healthBarTop: -5.0,
    );
    add(healthBar!);
  }

  @override
  void update(double dt) {
    super.update(dt);
    if (game.bloc.state.isGameOver || state == ZombieStateEnumType.dying) {
      return;
    }
    _walkingUpdate(dt);
  }

  @override
  Future<void> onCollision(
    Set<Vector2> intersectionPoints,
    PositionComponent other,
  ) async {
    if (other is Plant &&
        _currentPlant != other &&
        state != ZombieStateEnumType.eating) {
      _startEatingPlant(other);
    }
    super.onCollision(intersectionPoints, other);
  }

  // 僵尸行走
  void _walkingUpdate(double dt) {
    position.x -= speed * dt;
    if (position.x <= -width) {
      world.gameOver();
    }
  }

  // 僵尸吃植物
  void _startEatingPlant(Plant plant) async {
    state = ZombieStateEnumType.eating;
    _currentPlant = plant;
    speed = 0;
    await SoundManager().playEatingPlant();
    await super.setSpriteAnimation(
      diffParam: SpriteAnimationParamEntity.zombieEat,
    );
    _eatingTimer = TimerComponent(
      period: eatingPeriod,
      repeat: true,
      onTick: _attackPlantTick,
    );
    add(_eatingTimer!);
  }

  // 吃植物
  void _attackPlantTick() async {
    _currentPlant?.healthBar?.currentHealth -= attack;
    if (_currentPlant == null || _currentPlant!.healthBar!.currentHealth <= 0) {
      await finishEatingPlant();
    }
  }

  // 吃掉植物
  Future<void> finishEatingPlant() async {
    _currentPlant?.cell.plant = null;
    await SoundManager().stopEatingPlantSound();
    await SoundManager().playAtePlant();
    if (_currentPlant?.parent != null) {
      _currentPlant?.bodyShadow.removeFromParent();
      _currentPlant?.removeFromParent();
    }
    _currentPlant = null;
    await super.setSpriteAnimation(); // 改变为行走
    speed = zombieSpeed; // 继续前进
    _eatingTimer?.removeFromParent();
    state = ZombieStateEnumType.walking;
  }

  // 重置僵尸的各种数值
  Future<void> reset(int newRow) async {
    row = newRow;
    position = Vector2(
      game.size.x,
      lawnTopLeft.y + row * cellSize.y,
    );
    speed = zombieSpeed;
    _currentPlant = null;
    await setSpriteAnimation();
    if (healthBar != null) {
      healthBar!.currentHealth = maxHp;
      add(healthBar!);
    }
    _eatingTimer?.removeFromParent();
    _eatingTimer = null;
  }

  // 僵尸洗了
  Future<void> died() async {
    removeHitBox();
    // 加上一颗会飞的头
    world.add(
      NormalZombieHead(
        groundY: position.y + size.x,
        initPosition: position.clone() + Vector2(size.x / 2, 0),
      ),
    );
    // 吃的时候被干掉了，则停止吃
    if (state == ZombieStateEnumType.eating) {
      state = ZombieStateEnumType.dying;
      _eatingTimer?.removeFromParent();
      await SoundManager().stopEatingPlantSound();
    }
    state = ZombieStateEnumType.dying;
    final randomIndex = Random().nextInt(2);
    await super.setSpriteAnimation(
      diffParam: zombieDeathAnimations[randomIndex],
      loop: false,
    );
    Future.delayed(Duration(seconds: 3), () {
      bodyShadow.removeFromParent();
      removeFromParent();
    });
  }

  // 收到植物的攻击
  void underAttack() {
    children.whereType<ColorEffect>().forEach((e) => e.removeFromParent());
    add(
      ColorEffect(
        GameColors.zombieUnderAttackColor,
        EffectController(duration: 0.02, reverseDuration: 0.02),
      ),
    );
  }
}
